<template>
  <div>
    <el-table
      v-loading="showLoading"
      v-bind="$attrs"
      :data="tableData"
      style="width: 100%"
      @row-click="onRowClick"
      :element-loading-text="loadingAttr?.elementLoadingText"
      :element-loading-spinner="loadingAttr?.elementLoadingSpinner"
      :element-loading-svg-view-box="loadingAttr?.elementLoadingSvgViewBox"
      :element-loading-background="loadingAttr?.elementLoadingBackground"
    >
      <template v-for="(item, index) in tableOption" :key="index">
        <el-table-column
          :align="item.align"
          :prop="item.prop"
          :label="item.label"
          :width="item.width"
        >
          <template #default="scope">
            <template v-if="scope.row.rowEdit">
              <el-input v-model="scope.row[item.prop]"></el-input>
            </template>
            <template
              v-else-if="currentEditCell === scope.column.id + scope.$index"
            >
              <div class="flex">
                <el-input v-model="scope.row[item.prop]"></el-input>
                <div class="icons">
                  <el-icon-check
                    class="icon"
                    @click.stop="cellSubmit(scope)"
                  ></el-icon-check>
                  <el-icon-close
                    class="icon"
                    @click.stop="cellCancel(scope)"
                  ></el-icon-close>
                </div>
              </div>
            </template>
            <template v-else>
              <slot v-if="item.slot" :name="item.slot" :scope="scope"></slot>
              <template v-else-if="item.prop && !item.action">
                {{ scope.row[item.prop] }}
              </template>
              <component
                :is="`el-icon${toLine(editIcon)}`"
                class="icon"
                v-if="item.editable"
                @click.stop="columnClick(scope)"
              >
              </component>
            </template>
          </template>
        </el-table-column>
      </template>
      <el-table-column
        :label="actionOption?.label"
        :width="actionOption?.width"
        :align="actionOption?.align"
      >
        <template #default="scope">
          <slot name="editRow" v-if="scope.row.rowEdit" :scope="scope"></slot>
          <slot name="action" v-else :scope="scope"></slot>
        </template>
      </el-table-column>
    </el-table>
    <el-pagination
      :style="{ justifyContent }"
      class="page-box"
      :current-page="currentPage"
      :page-size="pageSize"
      :page-sizes="pageSizes"
      layout="total, sizes, prev, pager, next, jumper"
      :total="total"
      :background="true"
      @size-change="handleSizeChange"
      @current-change="handleCurrentChange"
    />
  </div>
</template>

<script setup lang="ts">
import { ref, PropType, computed, watch, onMounted } from "vue";
import { TableOptions, TableLoadingOptions } from "./types.ts";
import { toLine } from "../../../utils/index.ts";
import { cloneDeep } from "lodash-es";
const emits = defineEmits([
  "cellSubmit",
  "cellCancel",
  "update:editRowIndex",
  "sizeChange",
  "currentChange",
]);
const props = defineProps({
  options: {
    type: Array<TableOptions>,
    default: () => [],
    required: true,
  },
  data: {
    type: Array as PropType<any[]>,
    default: () => [],
    required: true,
  },
  loadingAttr: {
    type: Object as PropType<TableLoadingOptions>,
    default: {},
  },
  // 编辑显示的图标
  editIcon: {
    type: String,
    default: "Edit",
  },
  // 是否可以编辑行
  isEditRow: {
    type: Boolean,
    default: false,
  },
  // 编辑行按钮的标识
  editRowIndex: {
    type: String,
    default: "",
  },
  // 是否显示分页
  pagination: {
    type: Boolean,
    default: false,
  },
  // 显示分页的对齐方式
  paginationAlign: {
    type: String as PropType<"left" | "center" | "right">,
    default: "left",
  },
  // 当前是第几页
  currentPage: {
    type: Number,
    default: 1,
  },
  // 当前一页多少条数据
  pageSize: {
    type: Number,
    default: 10,
  },
  // 显示分页数据多少条的选项
  pageSizes: {
    type: Array,
    default: () => [10, 20, 30, 40],
  },
  // 数据总条数
  total: {
    type: Number,
    default: 0,
  },
});

const justifyContent = computed(() => {
  switch (props.paginationAlign) {
    case "left":
      return "flex-start";
    case "center":
      return "flex-center";
    case "right":
      return "flex-end";
  }
});

let showLoading = computed(() => {
  return props.data.length > 0 ? false : true;
});
//表格正常数据展示
let tableOption = computed(() => {
  return props.options.filter((item: TableOptions) => {
    return !item.action;
  });
});
//表格操作列
let actionOption = computed(() => {
  return props.options.find((item: TableOptions) => {
    return item.action;
  });
});

// 编辑的单元格  index+id 在table里为唯一值
let currentEditCell = ref<string>("");

//点击单元格的编辑按钮
function columnClick(scope: any) {
  currentEditCell.value = scope.column.id + scope.$index;
}
//编辑单元格
function cellSubmit(scope: any) {
  emits("cellSubmit", scope);
  currentEditCell.value = "";
}
//取消编辑单元格
function cellCancel(scope: any) {
  emits("cellCancel", scope);
  currentEditCell.value = "";
}

// 拷贝一份表格的数据
let tableData = ref<any[]>(cloneDeep(props.data));
onMounted(() => {
  tableData.value.map((item) => {
    item.rowEdit = false;
  });
});
// 拷贝一份按钮的标识
let cloneEditRowIndex = ref<string>(props.editRowIndex);
// 监听的标识

// 如果data的数据变了 要重新给tableData赋值
// 只需要监听一次就可以了
watch(
  () => props.data,
  (val) => {
    // watchData.value = true;
    tableData.value = val;
    tableData.value.map((item) => {
      item.rowEdit = false;
    });
  },
  { deep: true }
);
// 监听
watch(
  () => props.editRowIndex,
  (val) => {
    if (val) cloneEditRowIndex.value = val;
  }
);
//行点击
function onRowClick(row: any, column: any) {
  console.log(row, column);
  //判断点击事件 是由action模块发出的
  if (
    column.label === actionOption.value?.label &&
    cloneEditRowIndex.value === props.editRowIndex
  ) {
    //将该行的所有data的rowEdit都变为true
    if (props.isEditRow) {
      // 编辑行的操作
      row.rowEdit = !row.rowEdit;
      // 重置其他数据的rowEdit
      tableData.value.map((item) => {
        if (item !== row) item.rowEdit = false;
      });
      // 重置按钮的标识
      if (!row.rowEdit) {
        emits("update:editRowIndex", "");
      }
    }
  }
}
function handleSizeChange(val: number) {
  emits("sizeChange", val);
}
function handleCurrentChange(val: number) {
  emits("currentChange", val);
}
</script>

<style lang="scss" scoped>
.flex {
  display: flex;
  align-items: center;
}
.icons {
  display: flex;
  justify-content: space-around;
  align-items: center;
}
.icon {
  width: 1em;
  height: 1em;
  cursor: pointer;
  position: relative;
  top: 2px;
  margin-left: 10px;
}
.page-box {
  margin: 10px 0;
  display: flex;
}
</style>
